package pl.edu.agh.student.se.kierunki;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.SpringLayout;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.JButton;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.FactHandle;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class MainWindow {

	private JFrame frame;
	private JTable table;
	private JScrollPane scrollPane_1;
	private JTable table_1;
	private String[] columns;
	private String[] columns_2;
	
	private List<Fakt> fakty = new LinkedList<Fakt>();
	private List<FactHandle> handles = new LinkedList<FactHandle>();
	private List<FactHandle> handles_h = new LinkedList<FactHandle>();
	private List<FactHandle> handles_p = new LinkedList<FactHandle>();
	private StatefulKnowledgeSession ksession;
	private DefaultTableModel model_1;
	private DefaultTableModel model_2;
	private List<Fakt> h = new LinkedList<Fakt>();
	private List<Fakt> p = new LinkedList<Fakt>();
	private KnowledgeBase kbase;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainWindow window = new MainWindow();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 * @throws Exception 
	 */
	public MainWindow() throws Exception {
	    kbase = readKnowledgeBase();
		initDrools();
		initialize();
		
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setTitle("Wybor kierunku studiow");
		frame.setBounds(100, 100, 800, 400);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		SpringLayout springLayout = new SpringLayout();
		frame.getContentPane().setLayout(springLayout);
		
		JScrollPane scrollPane = new JScrollPane();
		springLayout.putConstraint(SpringLayout.NORTH, scrollPane, 10, SpringLayout.NORTH, frame.getContentPane());
		springLayout.putConstraint(SpringLayout.WEST, scrollPane, 10, SpringLayout.WEST, frame.getContentPane());
		springLayout.putConstraint(SpringLayout.SOUTH, scrollPane, -10, SpringLayout.SOUTH, frame.getContentPane());
		springLayout.putConstraint(SpringLayout.EAST, scrollPane, -395, SpringLayout.EAST, frame.getContentPane());
		frame.getContentPane().add(scrollPane);
		
		columns = new String[] {
				"Fakt", "Pewnosc", "wiarygodnosc"
		};
		
		columns_2 = new String[] {
				"Fakt", "Pewnosc"
		};
		
		Object[][] t1 = new Object[fakty.size()][];
		for(int i=0; i< fakty.size(); i++){
			t1[i] = new Object[4];
			t1[i][0] = fakty.get(i).getNazwa().getLabel();
			t1[i][1] = fakty.get(i).getPewnosc()*100;
			t1[i][2] = fakty.get(i).getWiarygodnosc()*100;
		}
		
		model_1 = new DefaultTableModel(t1, columns) {
			Class[] columnTypes = new Class[] {
					Object.class, Double.class, Double.class
				};
				public Class getColumnClass(int columnIndex) {
					return columnTypes[columnIndex];
				}
				boolean[] columnEditables = new boolean[] {
					false, true, true, true
				};
				public boolean isCellEditable(int row, int column) {
					return columnEditables[column];
				}
			};
			
		model_1.addTableModelListener(new TableModelListener(){

			@Override
			public void tableChanged(TableModelEvent ev) {
				
				for(int i=0; i<fakty.size(); i++){
					fakty.get(i).setPewnosc(0.0);
					fakty.get(i).setWiarygodnosc(0.5);
				}
				
				for(Fakt f: h){
					f.setPewnosc(0.0);
					f.setWiarygodnosc(0.5);
				}
				
				for(Fakt f: p){
					f.setPewnosc(0.0);
					f.setWiarygodnosc(0.5);
				}
				
				for(int i=0; i< fakty.size(); i++){
//					System.out.println(i);
				
					Double v = (Double)model_1.getValueAt(i, ev.getColumn());
					if(ev.getColumn() == 1)
						fakty.get(i).setPewnosc(v/100.0);
					else
						fakty.get(i).setWiarygodnosc(v/100.0);
				}

				for(int i=0; i<fakty.size(); i++){
//					System.out.println(fakty.get(i).getPewnosc());
//					System.out.println("changed(): "+fakty.get(i).getNazwa()+" "+fakty.get(i).getPewnosc());
					ksession.update(handles.get(i), fakty.get(i));
				}
				
				for(int i=0; i<h.size(); i++){
//					System.out.println(fakty.get(i).getPewnosc());
					ksession.update(handles_h.get(i), h.get(i));
				}
				
				for(int i=0; i<p.size(); i++){
					ksession.update(handles_p.get(i), p.get(i));
				}
				
				ksession.fireAllRules();
				
				Object[][] t = new Object[h.size()][];
				for(int i=0; i< h.size(); i++){
					t[i] = new Object[2];
					t[i][0] = h.get(i).getNazwa().getLabel();
					t[i][1] = h.get(i).getPewnosc()*100.0;
				}
				
				model_2.setDataVector(t, columns_2);
			}});	
		
		table = new JTable();
		table.setModel(model_1);
		
//		table.getColumnModel().getColumn(0).setPreferredWidth(70);
//		table.getColumnModel().getColumn(1).setResizable(false);
//		table.getColumnModel().getColumn(1).setPreferredWidth(70);
//		table.getColumnModel().getColumn(1).setMaxWidth(70);
		scrollPane.setViewportView(table);
		
		scrollPane_1 = new JScrollPane();
		springLayout.putConstraint(SpringLayout.WEST, scrollPane_1, 10, SpringLayout.EAST, scrollPane);
		springLayout.putConstraint(SpringLayout.NORTH, scrollPane_1, 10, SpringLayout.NORTH, frame.getContentPane());
		springLayout.putConstraint(SpringLayout.SOUTH, scrollPane_1, -10, SpringLayout.SOUTH, frame.getContentPane());
		springLayout.putConstraint(SpringLayout.EAST, scrollPane_1, -10, SpringLayout.EAST, frame.getContentPane());
		frame.getContentPane().add(scrollPane_1);
		
		table_1 = new JTable();
		Object[][] t2 = new Object[fakty.size()][];
		for(int i=0; i< h.size(); i++){
			t2[i] = new Object[2];
			t2[i][0] = h.get(i).getNazwa().getLabel();
			t2[i][1] = h.get(i).getPewnosc()*100;
		}
		
		model_2 = new DefaultTableModel(t2, columns_2) {
			Class[] columnTypes = new Class[] {
				Object.class, Double.class
			};
			public Class getColumnClass(int columnIndex) {
				return columnTypes[columnIndex];
			}
			boolean[] columnEditables = new boolean[] {
				false, true
			};
			public boolean isCellEditable(int row, int column) {
				return columnEditables[column];
			}
		};
		
		table_1.setModel(model_2);
		table_1.getColumnModel().getColumn(1).setResizable(false);
		table_1.getColumnModel().getColumn(1).setMaxWidth(70);
		scrollPane_1.setViewportView(table_1);
	}
	
	private  KnowledgeBase readKnowledgeBase() throws Exception {
		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		kbuilder.add(ResourceFactory.newClassPathResource("kierunki.drl"), ResourceType.DRL);
		KnowledgeBuilderErrors errors = kbuilder.getErrors();
		if (errors.size() > 0) {
			for (KnowledgeBuilderError error: errors) {
				System.err.println(error);
			}
			throw new IllegalArgumentException("Could not pa	rse knowledge.");
		}
		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
		return kbase;
	}

	public void initDrools() throws Exception{
		// load up the knowledge bas
		ksession = kbase.newStatefulKnowledgeSession();
		//KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
		
		Fakt f112 = new Fakt(FaktTyp.K_TECHNICZNE);
		Fakt f113 = new Fakt(FaktTyp.K_ARTYSTYCZNE);
		Fakt f114 = new Fakt(FaktTyp.K_SPOLECZNE);
		Fakt f118 = new Fakt(FaktTyp.K_MEDYCZNE);
		Fakt f116 = new Fakt(FaktTyp.K_BIOLOGICZNE);
		Fakt f115 = new Fakt(FaktTyp.K_SPORTOWE);
		Fakt f117 = new Fakt(FaktTyp.K_HUMANISTYCZNE);
		Fakt f111 = new Fakt(FaktTyp.K_EKONOMICZNE);
		
		fakty.clear();
		for(FaktTyp ft : FaktTyp.values()){
			if(ft == FaktTyp.Z_LICZBOWE)
				break;
			fakty.add(new Fakt(ft));
		}
		
		List<FaktTyp> types = Arrays.asList(FaktTyp.values());
		for(int i = types.indexOf(FaktTyp.Z_LICZBOWE); i<=types.indexOf(FaktTyp.S_FIZYCZNA); i++){
			Fakt f = new Fakt(types.get(i));
			p.add(f);
			handles_p.add(ksession.insert(f));
		}
		
		h.add(f111);
		h.add(f112);
		h.add(f113);
		h.add(f114);
		h.add(f115);
		h.add(f116);
		h.add(f117);
		h.add(f118);
		
		for(Fakt f: fakty){
			handles.add(ksession.insert(f));
		}
		
		for(Fakt f: h){
			handles_h.add(ksession.insert(f));
		}
		
		ksession.fireAllRules();
	
	}
}
